package com.jiuqi.abc.model.service;

import com.jiuqi.abc.intf.ABCIntfException;
import com.jiuqi.abc.intf.provider.dimension.DimBean;
import com.jiuqi.abc.intf.provider.dimension.IDimProvider;
import com.jiuqi.abc.intf.provider.member.IMemberProvider;
import com.jiuqi.abc.intf.provider.member.Member;
import com.jiuqi.abc.model.bean.DriverItem;
import com.jiuqi.abc.model.bean.DriverItemFormula;
import com.jiuqi.abc.model.dao.ABCDriverItemDao;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 动因项service
 *
 * @author 龚泽楷
 * @date 2023年04月23日 13:31
 */
@Service
public class ABCDriverItemService {

    @Autowired
    private ABCDriverItemDao abcDriverItemDao;

    @Autowired
    private ABCDriverItemFormulaService abcDriverItemFormulaService;

    @Autowired
    IDimProvider dimProvider;

    @Autowired
    IMemberProvider memberProvider;

    private static final Logger logger = LoggerFactory.getLogger(ABCDriverItemService.class);

    /**
     * 批量增加动因项
     *
     * @param driverItems 动因项集合
     */
    public void batchAddDriverItem(List<DriverItem> driverItems) {
        abcDriverItemDao.batchAddDriverItem(driverItems);
    }

    /**
     * 根据 动因ID集合 批量获取 动因项集合
     *
     * @param driverIds 动因ID集合
     * @return 动因项集合
     */
    public List<DriverItem> getDriverItemListByDriverIds(List<String> driverIds) {
        return abcDriverItemDao.getDriverItemListByDriverIds(driverIds);
    }

    /**
     * 根据  动因分组ID 批量获取 动因项列表
     *
     * @param driverGroupId 动因分组ID
     * @return 动因项列表【注意：动因项 中 没有 动因项公式】
     */
    public List<DriverItem> getDriverItemListByDriverGroupId(String driverGroupId) {
        return abcDriverItemDao.getDriverItemListByDriverGroupId(driverGroupId);

    }


    /**
     * 根据 动因分组ID 和 时期参数 批量获取 动因项列表
     *
     * @param driverGroupId 动因分组ID
     * @param period        时期参数
     * @return 动因项列表 【注意：动因项中 有 动因项公式 ， 有 维度名称、维度项名称】
     */
    public List<DriverItem> getDriverItemListByDriverGroupIdAndPeriod(String driverGroupId, String period) {
        List<DriverItem> driverItemList = getDriverItemListByDriverGroupId(driverGroupId);

        List<String> driverItemIdList = new ArrayList<>();
        for (DriverItem driverItem : driverItemList) {
            driverItemIdList.add(driverItem.getId());
        }

        //根据 动因项ID集合 批量获取 动因项公式信息集合
        //动因项ID集合 不为空时  查询 动因项公式
        if (!driverItemIdList.isEmpty()) {
            List<DriverItemFormula> driverItemFormulaList = abcDriverItemFormulaService.batchGetDriverItemFormulaByDriverItemIdList(driverItemIdList);
            return assemableDriverItemFormulaForDriverItem(period, driverItemList, driverItemFormulaList);
        }

        return driverItemList;
    }

    /**
     * 根据 模型ID 获取 动因项集合
     *
     * @param modelId 模型ID
     * @return 动因项集合 【注意：动因项中 有 动因项公式 ，没有 维度名称、维度项名称】
     */
    public List<DriverItem> getDriverItemListByModelId(String modelId) {
        List<DriverItem> driverItemList = abcDriverItemDao.getDriverItemListByModelId(modelId);

        List<String> driverItemIdList = new ArrayList<>();
        for (DriverItem driverItem : driverItemList) {
            driverItemIdList.add(driverItem.getId());
        }

        //根据 动因项ID集合 批量获取 动因项公式信息集合
        //动因项ID集合 不为空时  查询 动因项公式
        if (!driverItemIdList.isEmpty()) {
            List<DriverItemFormula> driverItemFormulaList = abcDriverItemFormulaService.batchGetDriverItemFormulaByDriverItemIdList(driverItemIdList);

            //先分组形成map,后将map流化，给匹配的 动因项 添加 动因项公式
            driverItemFormulaList.stream()
                    .collect(Collectors.groupingBy(DriverItemFormula::getBelongDriverItemId))
                    .forEach((key, value) ->
                            driverItemList.stream()
                                    .filter(item -> key.equals(item.getId()))
                                    .forEach(driverItem -> {
                                        //设置动因项，一个动因项对应一个动因项公式
                                        if (value.get(0) != null)
                                            driverItem.setDriverItemFormula(value.get(0));
                                    })
                    );
        }
        return driverItemList;
    }

    /**
     * 为 动因项 装配 动因项公式,动因项中装配 维度名称、维度项名称
     *
     * @param period                时期参数
     * @param driverItemList        动因项集合
     * @param driverItemFormulaList 动因项公式集合
     * @return 装配好 动因项公式 的 动因项
     */
    public List<DriverItem> assemableDriverItemFormulaForDriverItem(String period, List<DriverItem> driverItemList, List<DriverItemFormula> driverItemFormulaList) {
        //先分组形成map,后将map流化，给匹配的 动因项 添加 动因项公式
        driverItemFormulaList.stream()
                .collect(Collectors.groupingBy(DriverItemFormula::getBelongDriverItemId))
                .forEach((key, value) ->
                        driverItemList.stream()
                                .filter(item -> key.equals(item.getId()))
                                .forEach(driverItem -> {
                                    //设置动因项，一个动因项对应一个动因项公式
                                    if (value.get(0) != null)
                                        driverItem.setDriverItemFormula(value.get(0));

                                    try {

                                        //获取维度名称
                                        String dimName = driverItem.getDimName();
                                        DimBean dim = dimProvider.getBean(dimName);
                                        String dimTitle = dim.getTitle();
                                        driverItem.setDimTitle(dimTitle);
                                        //获取维度项名称
                                        String memberCode = driverItem.getMemberCode();
                                        Member member = memberProvider.get(dimName, memberCode, period);
                                        String dimItemName = member.getName();
                                        driverItem.setDimItemName(dimItemName);

                                    } catch (ABCIntfException ex) {
                                        logger.error("ABC接口异常", ex);
                                    }
                                })
                );
        return driverItemList;
    }

    /**
     * 根据 动因ID集合 批量删除 动因项
     *
     * @param driverIdList 不同动因ID集合
     */
    @Transactional(rollbackFor = Exception.class)
    public void batchDeleteDriverItemsByDriverIds(List<String> driverIdList) {
        List<String> driverItemIdList = new ArrayList<>();
        List<DriverItem> driverItems = abcDriverItemDao.getDriverItemListByDriverIds(driverIdList);
        for (DriverItem driverItem : driverItems) {
            driverItemIdList.add(driverItem.getId());
        }

        abcDriverItemFormulaService.batchDeleteDriverItemFormula(driverItemIdList);

        abcDriverItemDao.batchDeleteDriverItem(driverIdList);
    }


}
